#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include "myhttp.h"

void * handler ( void * sockfd )
{
   char * buf = malloc ( 1024 );
   ssize_t size = recv ( *(( int* ) sockfd ), ( void *) buf, 1023, 0 );
   char *filename = malloc ( 256 );
   char *buffer = malloc ( 16384 );
   FILE *file;
   size_t read;
   size_t send_size;
   char ending [ 256 ];
   char type [ 256 ];
   char full_filename [256];
   int i, j;
   printf ( "past variable declaration\n" );
   filename = getFileNameFromHTTPRequest (( void * ) buf, 1023 );
   printf ( "got filename : %s\n", filename );
   HTTPResponse res;
   if ( filename  != NULL )
   {
      if ( !strcmp ( filename, "/" ))
      {
         strcpy ( full_filename, "index.html" );
      }
      else
      {
         for ( i = 1; i< 255; i++ )
         {
            full_filename [ i - 1 ] = filename [ i ];
            full_filename [ 254 ] = '\0';
         }
         full_filename [ strlen ( full_filename )] = '\0';
      }
      file = fopen ( full_filename, "r" );
      if ( file == NULL )
      {
         res = getFileNotFoundResponseString ();
      }
      else
      {
         read = fread ( buffer, 1, 16384, file );
         for ( i = strlen ( full_filename ) - 1 ; i >= 0; i-- )
         {
            if ( full_filename [ i ] == '.' )
            {
               for ( j = 0; i < strlen ( full_filename ); j++, i++ )
               {
                  ending [ j ] = full_filename [ i ];
               }
               printf ( "length :%i\n", strlen( ending ) );
               break;
            }
         }
         printf ( "ending %s\n", ending );
         if ( !strncmp ( ending, ".html" , 4))
         {
            strcpy ( type, "text/html" );
         }
         else if ( !strncmp ( ending, ".htm", 3 ))
         {
            strcpy ( type, "text/html");
         }
         else if ( !strncmp ( ending, ".png", 3 ))
         {
            strcpy ( type, "image/png");
         }
         else if ( !strncmp ( ending, ".jpg", 3 ))
         {
            strcpy ( type, "image/jpg" );
         }
         else
         {
            strcpy ( type, "text/unknown" );
         }
         res = getResponseString ( type, buffer, read );
      }
   }
   else
   {
      res = getNotImplementedResponseString ();
   }
   printf ( "before response \n" );
   printf ( "response : %s\n", res.vptrResponse );
   printf ( "length = %i\n", res.length );
   send_size = send ((* (( int *) sockfd)), res.vptrResponse, res.length, 0 );
   size_t total = send_size;
   while ( total < res.length )
   {
      if ( send_size == -1 )
      {
         perror ( "oh noes" );
         break;
      }
      send_size = send ((* (( int *) sockfd)), res.vptrResponse, res.length, 0 );
      total += send_size;
   }
   printf ( "send_size = %i\n", send_size );
   shutdown((* (( int *) sockfd)), SHUT_RDWR );
   printf ( "after response \n" );
}

int main(int argc, char **argv)
{
	if (argc != 2)
	{
		fprintf(stderr, "Usage: %s <port number>\n", argv[0]);
		exit(1);
	}
   int sock = socket ( AF_INET, SOCK_STREAM, 0 );
   if ( sock == -1 )
   {
      exit ( 1 );
   }
   unsigned short port = atoi ( argv [ 1 ] );
   printf ( "Port : %i\n", port );
   struct sockaddr_in name;
   name.sin_family = AF_INET;
   name.sin_port = htons ( port );
   name.sin_addr.s_addr = htonl ( INADDR_ANY );
   memset ( name.sin_zero, '\0', sizeof ( name.sin_zero ));
   int ret = bind ( sock, ( struct sockaddr *) &name, sizeof ( name ));
   if ( ret == -1 )
   {
      perror ( "bind failed" );
      exit ( 1 );
   }
   ret = listen ( sock, 20 );
   if ( ret == -1 )
   {
      perror ( "listen failed" );
      exit ( 1 );
   }
   while ( 1 )
   {
      printf ( "entered while\n" );
      struct sockaddr_in endaddr;
      int size = sizeof ( endaddr );
      int sockfd = accept ( sock, ( struct sockaddr * ) & endaddr, &size );
      if ( sockfd != -1 )
      {
         printf ( "enter thread\n" );
         pthread_t * thread = malloc ( sizeof ( pthread_t));
         int ret = pthread_create ( thread, NULL, handler, ((void*) &sockfd));
         if ( ret != 0 )
         {
            perror ( "oh noes" );
         }
      }
   }
}
